﻿namespace DDDDemo1;

public class PaymentAppService : IPaymentAppService
{
    private readonly IAccountRepository _AccountRepository;
    private readonly IAccountTransferDomainService _AccountTransferDomainService;
    private readonly IBusiSafeService _BusiSafeService;
    private readonly IAuditMessageSenderProvider _AuditMessageSenderProvider;

    public PaymentAppService(
        IAccountRepository accountRepository,
        IAccountTransferDomainService accountTransferDomainService,
        IBusiSafeService busiSafeService,
        IAuditMessageSenderProvider auditMessageSenderProvider
        )
    {
        _AccountRepository = accountRepository;
        _AccountTransferDomainService = accountTransferDomainService;
        _BusiSafeService = busiSafeService;
        _AuditMessageSenderProvider = auditMessageSenderProvider;
    }

    public async Task<PayResult> PayAsync(
        Guid userId,
        string merchantAccountNo,
        decimal amount)
    {
        //加载数据
        var clientAccount = await _AccountRepository.FindAsync(userId);
        var merchantAccount = await _AccountRepository.FindAsync(merchantAccountNo);
        //交易检查
        var busiSafeCheckResult = await _BusiSafeService.CheckBusiAsync(userId, merchantAccountNo, amount);
        if (busiSafeCheckResult != BusiSafeStatus.Success)
        {
            throw new UserFriendlyException("风控验证不通过", "InvalidOper");
        }
        //转账业务
        await _AccountTransferDomainService.TransferAsync(clientAccount, merchantAccount, amount);
        //保持数据
        await _AccountRepository.UpdateAsync(clientAccount);
        await _AccountRepository.UpdateAsync(merchantAccount);
        //发送审计消息
        var message = new TransferAuditMessage
        {
            UserId = userId,
            ClientAccountNo = clientAccount.AccountNo,
            MerchantAccountNo = merchantAccountNo,
            Amount = amount,
            TransferTime = DateTime.Now,
            //...
        };
        await _AuditMessageSenderProvider.SendAsync(message);
        return new PayResult
        {
            IsSuccess = true,
        };
    }
}
